<template>
  <div class="update-container">
    <div class="column">
      <el-collapse>
        <el-collapse-item v-for="item in crawlerColumns" :key="item.id" :title="item.title" :name="item.id">
          <div v-for="column in item.children" :key="column.id" class="column-item">
            <span class="title">{{ column.title }}</span>
            <img :src="hasTask(column) ? selectedCrawler : noCrawler" width="18px" height="18px" alt="" @click="getColumnNode(column)">
          </div>
        </el-collapse-item>
      </el-collapse>
    </div>
    <div class="center">
      <el-tabs v-model="activeName" @tab-click="handleClick">
        <el-tab-pane label="任务管理" name="task">
          <task :tasks="tasks" @removeTask="removeTask" />
        </el-tab-pane>
        <el-tab-pane label="历史记录" name="record">
          <history ref="history" />
        </el-tab-pane>
        <el-tab-pane label="参数配置" name="setting">
          <setting />
        </el-tab-pane>
      </el-tabs>
    </div>
    <div class="chart">
      <div ref="weekChart" class="week-chart" />
    </div>
  </div>
</template>

<script>
import setting from './setting.vue'
import task from './task.vue'
import dayjs from 'dayjs'
import history from './history.vue'
import { showTip } from '@/utils'

export default {
  components: {
    setting,
    task,
    history
  },
  data() {
    return {
      crawlerColumns: [],
      activeName: 'task',
      tasks: [],
      selectedCrawler: require('@/assets/img/crawler_selected.png'),
      noCrawler: require('@/assets/img/crawler.png'),
      weekOptions: {
        title: {
          text: '爬取数量',
          subtext: '一周内爬取情况'
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        grid: {
          left: '2%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'value',
          boundaryGap: [0, 0.01]
        },
        yAxis: {
          type: 'category',
          data: []
        },
        series: [
          {
            type: 'bar',
            data: []
          }
        ]
      },
      tmpRun: []
    }
  },
  watch: {
    tasks: {
      handler(node) {
        if (!node[node.length - 1].taskId) return
        const timer = setInterval(async() => {
          const index = this.tasks.findIndex(item => !item.finished)
          if (index !== -1) {
            if (this.tmpRun.includes(this.tasks[index].taskId)) {
              this.tmpRun.splice(0, this.tmpRun.length)
              clearInterval(timer)
              return
            } else {
              this.tmpRun.push(this.tasks[index].taskId)
            }
            const res = await this.$api.getTaskList()
            if (res && res.code === 200) {
              const data = res.data.taskList
              this.tasks.forEach(taskItem => {
                if (!taskItem.finished) {
                  const taskIndex = data.findIndex(dataItem => dataItem.taskId === taskItem.taskId)
                  taskItem.num = data[taskIndex].num
                  if (data[taskIndex] && data[taskIndex].finished) {
                    taskItem.finished = true
                  }
                }
              })
            }
          } else {
            this.tmpRun.splice(0, this.tmpRun.length)
            clearInterval(timer)
          }
        }, 5000)
      },
      deep: true
    }
  },
  created() {
    this.getColumnTree()
    this.getWeekLogData()
    this.getTaskList()
  },
  mounted() {
    document.getElementsByClassName('app-main')[0].style.backgroundColor = '#fff'
  },
  destroyed() {
    document.getElementsByClassName('app-main')[0].style.backgroundColor = '#f0f2f5'
  },
  methods: {
    // 获取任务列表
    async getTaskList() {
      const res = await this.$api.getTaskList()
      if (res && res.code === 200) {
        const data = res.data.taskList
        data.map(item => {
          item.finished = true
          return item
        })
        this.tasks = data
      }
    },
    // 移除任务
    async removeTask(taskId) {
      const res = await this.$api.removeTask(taskId)
      if (res && res.code === 200) {
        const index = this.tasks.findIndex(item => item.taskId === taskId)
        this.tasks.splice(index, 1)
        this.$message.success('任务移除成功')
      } else {
        this.$message.error('任务移除失败')
      }
    },
    // 获取一周内爬取数据
    async getWeekLogData() {
      const res = await this.$api.getWeekLogData()
      if (res && res.code === 200) {
        const weekData = res.data.weekData
        for (let i = 0; i < 7; i++) {
          const day = dayjs().subtract(i, 'day').format('YYYY-MM-DD')
          this.weekOptions.yAxis.data.unshift(day)
          if (weekData[day]) {
            this.weekOptions.series[0].data.unshift(weekData[day])
          } else {
            this.weekOptions.series[0].data.unshift(0)
          }
        }
        this.initWeekChart()
      }
    },
    // 获取侧边栏
    async getColumnTree() {
      const res = await this.$api.getColumnTree()
      if (res && res.code === 200) {
        this.crawlerColumns = this.recursionChangeTree(res.data.records)
      }
    },
    // 递归改变树状结构
    recursionChangeTree(tree) {
      if (Array.isArray(tree) && tree.length > 0) {
        return tree.map(item => {
          this.$set(item, 'title', item.channelName || item.categoryName)
          if (item.children && Array.isArray(item.children)) {
            this.recursionChangeTree(item.children)
          }
          return item
        })
      } else {
        return []
      }
    },
    // 获取点击节点
    getColumnNode(node) {
      showTip.call(this, node.title, async() => {
        const hasTask = this.tasks.some(item => item.id === node.id)
        if (hasTask) {
          this.$message.error('该任务已经存在')
        } else {
          this.$message.success('开始爬取数据')
          this.tasks.push(node)
          const type = +localStorage.type || 1
          let res = null
          if (type === 1) {
            res = await this.$api.updateCourse(node)
          } else if (type === 2) {
            res = await this.$api.updateTerminfo(node)
          } else if (type === 3) {
            console.log(type)
          } else if (type === 4) {
            res = await this.$api.updateTeacher(node)
          }
          if (res && res.code === 200) {
            const { taskId, num } = res.data
            this.$set(node, 'taskId', taskId)
            this.$set(node, 'num', num)
            this.$set(node, 'finished', false)
          }
        }
      })
    },
    // 初始化图表
    initWeekChart() {
      const weekChart = this.$echarts.init(this.$refs.weekChart)
      weekChart.setOption(this.weekOptions)
      window.addEventListener('resize', () => {
        weekChart.resize()
      })
    },
    // 判断是否存在任务
    hasTask(node) {
      return this.tasks.some(item => item.id === node.id)
    },
    handleClick(tab, event) {
      if (this.activeName === 'record') {
        this.$refs.history.getLogList()
      }
    }
  }
}
</script>

<style lang="scss" scoped>
@import "@/styles/mixin.scss";

.update-container{
  display: flex;
  height: calc(100vh - 50px);
}

.column{
  flex-basis: 240px;
  width: 240px;
  overflow: auto;
  @include scrollBar;
  @include borderShadow(0px, 4px);
}

.center{
  flex: 3;
  padding: 0 10px;
  @include borderShadow(0px, 4px);
}

.chart{
  flex: 3;
  @include borderShadow(0px, 4px);
}
.week-chart{
  height: 400px;
}

.custom-tree-node{
  width: 100%;
  line-height: 28px;
  .btn{
    float: right;
  }
}
.column-item{
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 5px 20px 5px 15px;
  border-bottom: 1px solid #e7e7e7;
  &:hover{
    background: #f7f7f9;
  }
}
::v-deep .el-collapse-item__header{
  background: #e9edf0;
  height: 32px;
  padding-left: 10px;
  border-bottom: 1px solid #d3d3d3;
}
::v-deep .el-collapse-item__content{
  padding-bottom: 0;
}
::v-deep .app-main{
  background: #fff;
}
</style>
